//! 中文汇编器主程序
//! 
//! 命令行工具，用于将中文汇编代码编译为二进制文件

use chinese_assembler::*;
use std::env;
use std::path::{Path, PathBuf};
use std::process;

/// 解析命令行参数，确定架构
fn parse_architecture(args: &[String]) -> (Architecture, Vec<String>) {
    let mut arch = Architecture::I8086; // 默认8086
    let mut filtered_args = Vec::new();
    
    for arg in args.iter().skip(1) {
        // 检查架构参数
        if arg.starts_with("--arch=") {
            let arch_str = &arg[7..]; // 跳过 "--arch="
            arch = match Architecture::from_str(arch_str) {
                Some(a) => a,
                None => {
                    // 检查是否是计划支持但未实现的架构
                    let lower = arch_str.to_lowercase();
                    if lower == "80386" || lower == "i386" || lower == "386" {
                        eprintln!("警告: 80386 架构尚未实现，使用默认 8086");
                    } else if lower == "x64" || lower == "x86_64" || lower == "amd64" {
                        eprintln!("警告: x64 架构尚未实现，使用默认 8086");
                    } else {
                        eprintln!("警告: 未知架构 '{}'，使用默认 8086", arch_str);
                    }
                    Architecture::I8086
                }
            };
        } else if arg == "-h" || arg == "--help" {
            print_usage(&args[0]);
            process::exit(0);
        } else {
            filtered_args.push(arg.clone());
        }
    }
    
    (arch, filtered_args)
}

/// 打印使用说明
fn print_usage(program_name: &str) {
    eprintln!("用法: {} <输入文件> [输出文件] [选项]", program_name);
    eprintln!();
    eprintln!("选项:");
    eprintln!("  --arch=<架构>    指定目标架构");
    eprintln!("                   支持: 8086 (默认), 80386 (未实现), x64 (未实现)");
    eprintln!("                   示例: --arch=8086");
    eprintln!("  -h, --help       显示此帮助信息");
    eprintln!();
    eprintln!("架构:");
    eprintln!("  8086             16位 x86 架构 (默认)");
    eprintln!("  80386            32位 x86 架构 (计划支持)");
    eprintln!("  x64              64位 x86 架构 (计划支持)");
    eprintln!();
    eprintln!("支持格式: .bin (纯二进制), .com (DOS可执行文件)");
    eprintln!("未来支持: .exe (PE), .elf (ELF)");
}

fn main() {
    let args: Vec<String> = env::args().collect();

    if args.len() < 2 {
        print_usage(&args[0]);
        process::exit(1);
    }

    // 解析架构参数
    let (arch, filtered_args) = parse_architecture(&args);
    
    if filtered_args.is_empty() {
        print_usage(&args[0]);
        process::exit(1);
    }

    let input_file = &filtered_args[0];
    let output_file = filtered_args.get(1).map(|s| s.as_str()).unwrap_or("output.bin");

    // 确定输出格式
    let output_path = Path::new(output_file);
    let extension = output_path
        .extension()
        .and_then(|ext| ext.to_str())
        .unwrap_or("bin");
    
    let format = match OutputFormat::from_extension(extension) {
        Ok(f) => f,
        Err(e) => {
            eprintln!("错误: {}", e);
            process::exit(1);
        }
    };

    // 读取源文件
    let source = match utils::read_file(input_file) {
        Ok(content) => content,
        Err(e) => {
            eprintln!("错误: {}", e);
            process::exit(1);
        }
    };

    // 词法分析
    let lexer = Lexer::new(&source);
    
    // 语法分析
    let mut parser = match Parser::new(lexer) {
        Ok(p) => p,
        Err(e) => {
            eprintln!("解析错误: {}", e);
            process::exit(1);
        }
    };

    let program = match parser.parse_program() {
        Ok(p) => p,
        Err(e) => {
            eprintln!("解析错误: {}", e);
            process::exit(1);
        }
    };

    // 代码生成（根据架构选择编码器）
    let mut codegen = CodeGenerator::with_encoder(create_encoder(arch));
    let binary = match codegen.generate(&program) {
        Ok(b) => b,
        Err(e) => {
            eprintln!("代码生成错误: {}", e);
            process::exit(1);
        }
    };

    // 检查文件大小限制
    if let Err(e) = format.check_size_limit(binary.len()) {
        eprintln!("错误: {}", e);
        process::exit(1);
    }

    // 根据格式生成最终输出
    let final_output = match format.generate_output(&binary) {
        Ok(output) => output,
        Err(e) => {
            eprintln!("错误: {}", e);
            process::exit(1);
        }
    };

    // 使用用户指定的输出路径
    let final_output_path = PathBuf::from(output_file);

    // 创建输出目录（如果不存在）
    if let Some(parent) = final_output_path.parent() {
        if let Err(e) = std::fs::create_dir_all(parent) {
            eprintln!("错误: 无法创建输出目录: {}", e);
            process::exit(1);
        }
    }

    // 写入输出文件
    let output_file_str = final_output_path.to_str().unwrap_or(output_file);
    if let Err(e) = utils::write_file(output_file_str, &final_output) {
        eprintln!("写入错误: {}", e);
        process::exit(1);
    }

    // 显示架构信息
    println!("编译成功！架构: {}", arch.display_name());
    println!("输出文件: {} ({})", output_file_str, format.name());
    println!("生成 {} 字节的二进制代码", final_output.len());
    
    if format == OutputFormat::Com {
        println!("提示: 可以在 DOSBox 中直接运行此文件！");
    }
}
